package com.copa.ums.modules.ums.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.copa.ums.common.service.RedisService;
import com.copa.ums.modules.ums.mapper.UmsUserMapper;
import com.copa.ums.modules.ums.model.UmsResource;
import com.copa.ums.modules.ums.model.UmsUser;
import com.copa.ums.modules.ums.model.UmsUserRole;
import com.copa.ums.modules.ums.service.UmsUserCacheService;
import com.copa.ums.modules.ums.service.UmsUserRoleService;
import com.copa.ums.modules.ums.service.UmsUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author copa
 * @createDate 2022-10-31 16:46
 * @function redis操作实现类
 */
@Service
public class UmsUserCacheServiceImpl implements UmsUserCacheService {

    @Value("${redis.database}")
    private String REDIS_DATABASE;

    @Value("${redis.expire.common}")
    private Long REDIS_EXPIRE;

    @Value("${redis.key.user}")
    private String REDIS_KEY_USER;

    @Value("${redis.key.resourceList}")
    private String REDIS_KEY_RESOURCE_LIST;

    @Resource
    private RedisService redisService;

    @Resource
    private UmsUserMapper userMapper;

    @Resource
    private UmsUserRoleService userRoleService;

    @Override
    public UmsUser getUser(String username) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_USER + ":" + username;
        return (UmsUser) redisService.get(key);
    }

    @Override
    public void setUser(UmsUser user) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_USER + ":" + user.getUsername();
        redisService.set(key, user, REDIS_EXPIRE);
    }

    @Override
    public List<UmsResource> getResourceList(Long userId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + userId;
        return (List<UmsResource>) redisService.get(key);
    }

    @Override
    public void setResourceList(Long userId, List<UmsResource> resourceList) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + userId;
        redisService.set(key, resourceList, REDIS_EXPIRE);
    }

    @Override
    public void delUser(Long userId) {
        UmsUser user = userMapper.selectById(userId);
        if (userId != null) {
            String key = REDIS_DATABASE + ":" + REDIS_KEY_USER + ":" + user.getUsername();
            redisService.del(key);
        }
    }

    @Override
    public void delResourceList(Long userId) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":" + userId;
        redisService.del(key);
    }

    @Override
    public void delResourceListByResourceId(Long resourceId) {
        List<Long> userIdList = userMapper.getUserIdListByResourceId(resourceId);
        if (CollUtil.isNotEmpty(userIdList)) {
            String keyPrefix = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":";
            List<String> keys = userIdList.stream().map(adminId -> keyPrefix + adminId).collect(Collectors.toList());
            redisService.del(keys);
        }
    }

    @Override
    public void delResourceListByRoleIds(List<Long> roleIds) {
        QueryWrapper<UmsUserRole> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(UmsUserRole::getRoleId, roleIds);
        List<UmsUserRole> userRoleList = userRoleService.list(wrapper);
        if (CollUtil.isNotEmpty(userRoleList)) {
            String keyPrefix = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":";
            List<String> keys = userRoleList.stream().map(userRole -> keyPrefix + userRole.getUserId()).collect(Collectors.toList());
            redisService.del(keys);
        }
    }

    @Override
    public void delResourceListByRoleId(Long roleId) {
        QueryWrapper<UmsUserRole> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsUserRole::getRoleId, roleId);
        List<UmsUserRole> userRoleList = userRoleService.list(wrapper);
        if (CollUtil.isNotEmpty(userRoleList)) {
            String keyPrefix = REDIS_DATABASE + ":" + REDIS_KEY_RESOURCE_LIST + ":";
            List<String> keys = userRoleList.stream().map(userRole -> keyPrefix + userRole.getUserId()).collect(Collectors.toList());
            redisService.del(keys);
        }
    }
}
